/*
 * Unidata Platform Community Edition
 * Copyright (c) 2013-2020, UNIDATA LLC, All rights reserved.
 * This file is part of the Unidata Platform Community Edition software.
 *
 * Unidata Platform Community Edition is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Unidata Platform Community Edition is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
package org.unidata.mdm.draft.type;

import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.unidata.mdm.system.type.variables.Variables;

/**
 * @author Alexander Malyshev
 */
public class Draft {
    /**
     * ID of the provider (subsystem) that hanles this draft.
     */
    private String provider;
    /**
     * The draft object ID.
     */
    private final Long draftId;
    /**
     * A possibly existing parent draft object ID.
     */
    private Long parentDraftId;
    /**
     * The subject ID (i. e. the object, for which this draft exists).
     */
    private String subjectId;
    /**
     * Current owner of the draft.
     */
    private String owner;
    /**
     * Description.
     */
    private String description;
    /**
     * Date, at what the last edition was created.
     */
    private Date updateDate;
    /**
     * Date, at what the draft and first edition was created.
     */
    private Date createDate;
    /**
     * The creator's user name.
     */
    private String createdBy;
    /**
     * The updater's user name.
     */
    private String updatedBy;
    /**
     * The number of editions.
     */
    private int editionsCount;
    /**
     * The editions.
     */
    private List<Edition> editions;
    /**
     * The user tags.
     */
    private Collection<String> tags;
    /**
     * Free-form properties.
     */
    private Variables variables;
    /**
     * The draft publication order.
     */
    private DraftPublicationOrder publicationOrder;
    /**
     * Constructor.
     * @param draftId the draft id
     */
    public Draft(final Long draftId) {
        super();
        this.draftId = draftId;
    }
    /**
     * Resets the id
     * @param prev former version
     * @param id new id
     * @return draft
     */
    public static Draft reset(Draft prev, long id) {

        if (Objects.isNull(prev)) {
            return null;
        }

        Draft result = new Draft(id);

        result.setParentDraftId(prev.getParentDraftId());
        result.setSubjectId(prev.getSubjectId());
        result.setProvider(prev.getProvider());
        result.setDescription(prev.getDescription());
        result.setTags(prev.getTags());
        result.setEditionsCount(prev.getEditionsCount());
        result.setOwner(prev.getOwner());
        result.setCreateDate(prev.getCreateDate());
        result.setCreatedBy(prev.getCreatedBy());
        result.setUpdateDate(prev.getUpdateDate());
        result.setUpdatedBy(prev.getUpdatedBy());
        result.setPublicationOrder(prev.getPublicationOrder());

        return result;
    }
    /**
     * Returns true for draft id > 0.
     * @return true for draft id > 0
     */
    public boolean isExisting() {
        return Objects.nonNull(draftId) && draftId > 0L;
    }
    /**
     * Gets the draft id
     * @return id
     */
    public Long getDraftId() {
        return draftId;
    }
    /**
     * Gets the subject id.
     * @return id
     */
    public String getSubjectId() {
        return subjectId;
    }
    /**
     * @param subjectId the subjectId to set
     */
    public void setSubjectId(String subjectId) {
        this.subjectId = subjectId;
    }
    /**
     * Returns true, if subject id has not been set.
     * @return true for existing subject id
     */
    public boolean hasSubjectId() {
        return StringUtils.isNotBlank(subjectId);
    }
    /**
     * Gets the provider id.
     * @return id
     */
    public String getProvider() {
        return provider;
    }
    /**
     * Sets provider id
     * @param type the id
     */
    public void setProvider(String type) {
        this.provider = type;
    }
    /**
     * Gets owner.
     * @return owner
     */
    public String getOwner() {
        return owner;
    }
    /**
     * Sets owner.
     * @param owner the draft owner
     */
    public void setOwner(String owner) {
        this.owner = owner;
    }
    /**
     * Gets parent draft id or null
     * @return the parentDraftId
     */
    public Long getParentDraftId() {
        return parentDraftId;
    }
    /**
     * Sets parent draft id
     * @param parentDraftId the parentDraftId to set
     */
    public void setParentDraftId(Long parentDraftId) {
        this.parentDraftId = parentDraftId;
    }
    /**
     * Gets the update date
     * @return date
     */
    public Date getUpdateDate() {
        return updateDate;
    }
    /**
     * Sets the update date
     * @param updateDate the date
     */
    public void setUpdateDate(Date updateDate) {
        this.updateDate = updateDate;
    }
    /**
     * Gets description.
     * @return description
     */
    public String getDescription() {
        return description;
    }
    /**
     * Sets description.
     * @param decsription the description
     */
    public void setDescription(String decsription) {
        this.description = decsription;
    }
    /**
     * Gets the create date
     * @return date
     */
    public Date getCreateDate() {
        return createDate;
    }
    /**
     * Sets create date
     * @param createDate the date
     */
    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }
    /**
     * Gets the name of the user, who created the draft.
     * @return name
     */
    public String getCreatedBy() {
        return createdBy;
    }
    /**
     * Sets the name of the user, who created the draft.
     * @param createdBy the name
     */
    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }
    /**
     * Gets the name of the user, who updated the draft.
     * @return name
     */
    public String getUpdatedBy() {
        return updatedBy;
    }
    /**
     * Sets the name of the user, who updated the draft.
     * @param updatedBy the name
     */
    public void setUpdatedBy(String updatedBy) {
        this.updatedBy = updatedBy;
    }
    /**
     * Gets the number of editions of this draft.
     * @return the editionsCount
     */
    public int getEditionsCount() {
        return editionsCount;
    }
    /**
     * Sets the number of editions of this draft.
     * @param editionsCount the editionsCount to set
     */
    public void setEditionsCount(int editionsCount) {
        this.editionsCount = editionsCount;
    }
    /**
     * Gets editions.
     * @return the editions
     */
    public List<Edition> getEditions() {
        return Objects.isNull(editions) ? Collections.emptyList() : editions;
    }
    /**
     * Sets editions.
     * @param editions the editions to set
     */
    public void setEditions(List<Edition> editions) {
        this.editions = editions;
    }
    /**
     * Returns true, if the draft has some saved editions.
     * @return true, if the draft has some saved editions
     */
    public boolean hasEditions() {
        return editionsCount > 0;
    }
    /**
     * Gets this draft tags.
     * @return tags
     */
    public Collection<String> getTags() {
        return tags;
    }
    /**
     * Sets this draft tags.
     * @param tags the tags
     */
    public void setTags(Collection<String> tags) {
        this.tags = tags;
    }
    /**
     * @return the properties
     */
    public Variables getVariables() {
        return variables;
    }
    /**
     * @param properties the properties to set
     */
    public void setVariables(Variables properties) {
        this.variables = properties;
    }
    /**
     * @return the publicationOrder
     */
    public DraftPublicationOrder getPublicationOrder() {
        return Objects.isNull(publicationOrder) ? DraftPublicationOrder.CHILDREN_LAST : publicationOrder;
    }
    /**
     * @param publicationOrder the publicationOrder to set
     */
    public void setPublicationOrder(DraftPublicationOrder publicationOrder) {
        this.publicationOrder = publicationOrder;
    }
}
